package de.ff7rl.core.gamestate.intro;

import java.awt.Point;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

import com.thoughtworks.xstream.XStream;

import de.ff7rl.core.GameInfo;
import de.ff7rl.core.TerminalMenu;
import de.ff7rl.core.TerminalMenuItem;
import de.ff7rl.core.gamestate.AbstractGameStateController;
import de.ff7rl.core.gamestate.GameState;
import de.ff7rl.core.serialize.SaveState;

public class IntroGameStateController extends AbstractGameStateController {

  private enum IntroMenu {
    CONTINUE("Weiter"), NEW("Neu");

    private final String text;

    private IntroMenu(final String theText) {
      text = theText;
    }

    @Override
    public String toString() {
      return text;
    }
  }

  private static final List<String> AUTHORS = Arrays.asList("Klaus Hauschild", "Patrick Wilke");
  private static final XStream XSTREAM = new XStream();

  private TerminalMenu terminalMenu;

  @Override
  public void enter(final GameState thePreviousGameState, final Object... theArguments) {
    super.enter(thePreviousGameState);
    game().getTerminal().write(1, 1, " ______ _             _   ______          _                    ______");
    game().getTerminal().write(1, 2, "|  ____(_)           | | |  ____|        | |                  |____  |");
    game().getTerminal().write(1, 3, "| |__   _ _ __   __ _| | | |__ __ _ _ __ | |_ __ _ ___ _   _      / /");
    game().getTerminal().write(1, 4, "|  __| | | '_ \\ / _` | | |  __/ _` | '_ \\| __/ _` / __| | | |    / /");
    game().getTerminal().write(1, 5, "| |    | | | | | (_| | | | | | (_| | | | | || (_| \\__ \\ |_| |   / /");
    game().getTerminal().write(1, 6, "|_|    |_|_| |_|\\__,_|_| |_|  \\__,_|_| |_|\\__\\__,_|___/\\__, |  /_/");
    game().getTerminal().write(1, 7, "                                                        __/ |");
    game().getTerminal().write(1, 8, "                                                       |___/");
    game().getTerminal().write(1, 10, "                            _ _ _        ");
    game().getTerminal().write(1, 11, "                           | (_) |       ");
    game().getTerminal().write(1, 12, " _ __ ___   __ _ _   _  ___| |_| | _____ ");
    game().getTerminal().write(1, 13, "| '__/ _ \\ / _` | | | |/ _ \\ | | |/ / _ \\");
    game().getTerminal().write(1, 14, "| | | (_) | (_| | |_| |  __/ | |   <  __/");
    game().getTerminal().write(1, 15,
        "|_|  \\___/ \\__, |\\__,_|\\___|_|_|_|\\_\\___| version " + GameInfo.getVersion());
    game().getTerminal().write(1, 16, "            __/ |");
    game().getTerminal().write(1, 17, "           |___/ ");
    game().getTerminal().write(1, game().getTerminal().getTerminalSize().y - 2, "2011");
    for (int i = 0; i < AUTHORS.size(); i++) {
      final String author = AUTHORS.get(i);
      game().getTerminal().write(game().getTerminal().getTerminalSize().x - author.length() - 1,
          game().getTerminal().getTerminalSize().y - 2 - i, author);
    }
    terminalMenu = new TerminalMenu(game(), new Point(50, 30), Arrays.asList(new TerminalMenuItem(IntroMenu.NEW),
        new TerminalMenuItem(IntroMenu.CONTINUE)));
  }

  @Override
  public boolean input(final int theKeyCode) {
    switch (theKeyCode) {
      case KeyEvent.VK_UP :
        terminalMenu.previous();
        return true;
      case KeyEvent.VK_DOWN :
        terminalMenu.next();
        return true;
      case KeyEvent.VK_ENTER :
        if (terminalMenu.getSelectedItem().getValue() == IntroMenu.NEW) {
          game().newGameState(GameState.DUNGEON);
        } else {
          loadGame();
        }
        return true;
    }
    return false;
  }

  private void loadGame() {
    final JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));
    fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    fileChooser.setFileFilter(new FileNameExtensionFilter("Save state (*.save)", "save"));
    final int result = fileChooser.showOpenDialog(null);
    if (result != JFileChooser.APPROVE_OPTION) {
      return;
    }
    final File selectedFile = fileChooser.getSelectedFile();
    try {
      final SaveState saveState = (SaveState) XSTREAM.fromXML(new FileInputStream(selectedFile));
      game().load(saveState);
    } catch (final FileNotFoundException e) {
      throw new IllegalArgumentException(String.format("Unable to load save state from %s. Maybe corrupted.",
          selectedFile), e);
    }
  }

}
